/* M.Nielsen April 2008 mniel@cbs.dtu.dk */

/* 
Copyright (C) 2008-2015 Danish Technical University

This suite of programs and library routine is free software. You can 
redistribute it and/or modify it under the terms of the GNU General Public 
License as published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.

In other words, you are free to modify, copy, or redistribute this
source code and its documentation in any way you like, but you must
distribute all derivative versions as free software under the same
terms that I've provided my code to you (i.e. the GNU General Public
License). This precludes any use of the code in proprietary or
commercial software unless your source code is made freely available.

If you wish to use the code under a different Open Source license
that's not compatible with the GPL (like the Artistic License, BSD
license, or the Netscape Public License), please contact me
(Morten Nielsen, mniel@cbs.dtu.dk) for permission.

Incorporation into commercial software under non-GPL terms is possible
by obtaining a specially licensed version from The Danish Technical University.
Contact Morten Nielsen (mniel@cbs.dtu.dk) to arrange licensing terms.

This software is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
*/


#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "utils.h"

int p_npermut;
int seed;

PARAM	param[] = {
	"-nX", VINT	p_npermut, "Number times the dataset is oversampled in each holdout", "2",
	0
};



void generate_indices(int *vec, int length, int partitions, int *n)

{
	int	i;
	int j;
	int	w;
	int	t;
	float k;

	if (partitions > length || partitions < 2){
		printf( "Error: Non-sensical number of partitions\n");
		exit( 1 );
	}
	// Initialize vector, seeting "fraction" of the entries to values from 0 to (number of CV partitions - 1)
	i = 0;
	k = (1.0/partitions)*length;

	for (j = 1; j <= (partitions-1); j++){
		n[j-1] = 0;
		for (i; i < (int)(k*j); i++){
			vec[i] = j;
			n[j-1]++;
		}
	}
	
	srand(seed++);
	// Randomly shuffle
	for (i = length-1; i > 0; i--){
		w = rand()%(length-1);
		t = vec[i];
		vec[i] = vec[w];
		vec[w] = t;
	}
	
}

void	print_eval( int *vec, int n, PEPLIST *peplist )

{
	PEPLIST *pl;
	FILE	**fp_eval;
	WORD    tmp;
	int i;
	int *v;
	v = vec;
	
	fp_eval = malloc(n * sizeof(FILE*)); // ???????
	
	for (i = 0; i < n; i++) {
		sprintf(tmp, "H%d.eval", i + 1);
		if ( ( fp_eval[i] = fopen( tmp, "w" ) ) == NULL ) {
			printf( "Cannot open file %s\n", tmp );
			exit( 1 );
		}
	}
	for ( pl=peplist; pl; pl=pl->next ) {
		fprintf( fp_eval[*v], "%s %f\n", pl->pep, pl->score);
		v++;
	}
	for (i = 0; i < n; i++) {
		fclose( fp_eval[i] );
	}
}


void	print_traintest( int *vec, int eval, int *shfl, int test, char *filename, char *filename2, PEPLIST *peplist )
{
	PEPLIST *pl;
	FILE	*fp_train;
	FILE	*fp_test;
	int     *v, *s;
	
	v = vec;
	s = shfl;

	if ( ( fp_train = fopen( filename, "w" ) ) == NULL ) {
		printf( "Cannot open file %s\n", filename );
		exit( 1 );
	}
	if ( ( fp_test = fopen( filename2, "w" ) ) == NULL ) {
		printf( "Cannot open file %s\n", filename2 );
		exit( 1 );
	}
	for ( pl=peplist; pl; pl=pl->next, v++ ) {	
		if (*v != eval){
			if (*s == test) {
				fprintf( fp_test, "%s %f\n", pl->pep, pl->score);
			}
			else {
				fprintf( fp_train, "%s %f\n", pl->pep, pl->score);
			}
			s++;
		}
	}
	
	fclose( fp_train );
	fclose( fp_test );
}

/*
void	print_data( int *vec, char *filename, char *filename2, char *filename3, PEPLIST *peplist )

{
	PEPLIST *pl;
	FILE	*fp_eval;
	FILE	*fp_train;
	FILE	*fp_test;
	int	l = 0;

	if ( ( fp_eval = fopen( filename, "w" ) ) == NULL ) {
		printf( "Cannot open file %s\n", filename );
		exit( 1 );
	}
	if ( ( fp_train = fopen( filename2, "w" ) ) == NULL ) {
		printf( "Cannot open file %s\n", filename );
		exit( 1 );
	}
	if ( ( fp_test = fopen( filename3, "w" ) ) == NULL ) {
		printf( "Cannot open file %s\n", filename );
		exit( 1 );
	}
	for ( pl=peplist; pl; pl=pl->next ) {
		if (vec[l] == 1){
			fprintf( fp_eval, "%s %f\n", pl->pep, pl->score);
		} 
		else if (vec[l] == 2){
			fprintf( fp_test, "%s %f\n", pl->pep, pl->score);
		} else {
			fprintf( fp_train, "%s %f\n", pl->pep, pl->score);
		}
		l++;
	}
	
	fclose( fp_eval );
	fclose( fp_train );
	fclose( fp_test );
}
*/


main (int argc, char *argv[]){
	PEPLIST		*peplist, *pl;
	int *vec, *shfl, *nbin, *nbin2;
	int i, hout, permut;
	int set = 0;
	int ndat = 0;
	float	**inp;
	int	n;
	WORD fn_test, fn_train;
	
	seed = time(NULL);
	pparse( &argc, &argv, param, 1, "peptidefile" );

	set_pep_verbose(0);
	//inp = init_input( file, &nc, &n );
	peplist = peplist_read( argv[1] );

	for (n = 0, pl=peplist; pl; pl=pl->next, n++){}

	vec = ivector( 0, n-1 ); /* Allocate vector for input */
	nbin = ivector( 0, 4);

	generate_indices(vec, n, 5, nbin); //vector, number of entries, number of folds, vector for storing bin sizes
	
	print_eval(vec, 5, peplist);
	
	for( hout = 0; hout < 5; hout++){
		ndat = 0;
		set = 0;
		for (i = 0; i < 5; i++) {
			if (i != hout){
				ndat += nbin[i];
			}
			
		} 
		shfl = ivector( 0 , ndat-1);
		nbin2 = ivector( 0, 3);
		
		for (permut = 0; permut < p_npermut;  permut++ ) {
			generate_indices(shfl, ndat, 4, nbin2);
			for (i = 0; i < 4; i++) {
				
				sprintf(fn_train, "H%d.train.%03d", hout + 1, ++set );
				sprintf(fn_test,  "H%d.test.%03d", hout + 1,  set );
				
				print_traintest(vec, hout, shfl, i, fn_train, fn_test, peplist);
			}
		}
		ivector_free(shfl, 0, ndat-1 );
	}
	
	
	exit(0);
}
